package com.xxl.controller.impl;

import com.xxl.controller.UserApi;
import com.xxl.dto.BlogDto;
import com.xxl.dto.UserDto;
import com.xxl.service.BlogService;
import com.xxl.service.UserService;
import com.xxl.util.GlobalResult;
import com.xxl.util.JwtUtil;
import com.xxl.util.ModelData;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.sql.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xxl
 * @date 2023/4/5
 */
@RestController
@Slf4j
@RequestMapping(value = "/user", produces = "application/json")
public class UserApiImpl implements UserApi<Map<String, Object>> {
    @Resource
    JwtUtil util;
    @Resource
    GlobalResult resultUtil;
    @Resource
    UserService userService;
    @Resource
    NoAuthenticationApiImpl noAuthenticationApi;
    @Resource
    HttpServletRequest request;
    @Resource
    HttpServletResponse response;
    @Resource
    BlogService blogService;
    @Override
    @DeleteMapping("/logout")
    public Map<String, Object> logout() {
        noAuthenticationApi.clearSession();
        noAuthenticationApi.clearCookie();
        ModelData.USER_TOKEN = null;
        return resultUtil.result(200, "退出成功");
    }


    @Override
    @GetMapping("/allFollows")
    public Map<String, Object> AllFollows(String username) {
        if (JwtUtil.parseJwt(util.getToken()) instanceof HashMap<?, ?> map) {
            if (!username.equals(map.get("username"))) {
                return resultUtil.result(500, "查询失败，用户名与此账户名不正确");
            }
        }
        return resultUtil.result(200, "查询成功", userService.queryAllFollow(username));
    }

    @Override
    @GetMapping("/allFollowings")
    public Map<String, Object> AllFollowings(String username) {
        if (JwtUtil.parseJwt(util.getToken()) instanceof HashMap<?, ?> map) {
            if (!username.equals(map.get("username"))) {
                return resultUtil.result(500, "查询失败，用户名与此账户名不正确");
            }
        }
        return resultUtil.result(200, "查询成功", userService.queryAllFollowing(username));
    }

    @Override
    @PutMapping("/modify")
    public Map<String, Object> modifyAccountInfo(@RequestBody UserDto userDto) {
        //可以修改邮箱,性别,出生日期
        UserDto user = null;
        String email = userDto.getEmail();
        Integer gender = userDto.getGender();
        Date birth = userDto.getBirth();
        if (!email.isEmpty()) {
            if (!email.contains("@")) {
                return resultUtil.result(500, "邮箱格式错误");
            }
            if (user == null) {
                user = new UserDto();
            }
            user.setEmail(email);
        }
        if (gender != 2) {
            if (user == null) {
                user = new UserDto();
            }
            user.setGender(gender);
        }
        if (birth != null) {
            if (user == null) {
                user = new UserDto();
            }
            user.setBirth(birth);
        }
        if (user == null){
            return resultUtil.result(500,"参数不能为空");
        }
        userService.<UserDto>modifyUser(user, util.getTokenUser().getUsername());
        return resultUtil.result(200, "修改成功");
    }

    @Override
    @PostMapping("/modifyPassword")
    public Map<String, Object> modifyPassword(@RequestParam("password") String password) {
        UserDto user = new UserDto();
        user.setPassword(password);
        userService.<UserDto>modifyUser(user, util.getTokenUser().getUsername());
        return resultUtil.result(200, "修改成功");
    }

    @Override
    @GetMapping("/follow/{followName}")
    public Map<String, Object> followSomeone(@PathVariable("followName") String followName) {
        if (userService.findByUsername(followName) == null) {
            return resultUtil.result(500, "没有当前这个用户" + followName);
        }
        userService.followUser(followName, util.getTokenUser().getUsername());
        return resultUtil.result(200, "关注成功");
    }

    @Override
    @GetMapping("/canselFollow/{followName}")
    public Map<String, Object> cancelFollowSomeone(@PathVariable("followName") String followName) {
        if (userService.findByUsername(followName) == null) {
            return resultUtil.result(500, "没有当前这个用户" + followName);
        }
        userService.cancelFollowUser(followName, util.getTokenUser().getUsername());

        return resultUtil.result(200, "取消关注成功");
    }

    @Value("${fileAddress}")
    String realPath;
    /**
     * 头像上传
     * @param
     * @return
     */
    @Override
    @PostMapping("/upload")
    public Map<String, Object> pictureUpload(@RequestParam("file") MultipartFile file) throws IOException {
        //拿到token中user再查询
        UserDto tokenUser = util.getTokenUser();
        UserDto login = userService.login(tokenUser.getUsername(), tokenUser.getPassword());

        String originalFilename = file.getOriginalFilename();
        log.warn("文件名=" + originalFilename);
        String substring = originalFilename.substring(originalFilename.lastIndexOf(".")+1);
        log.warn("经过分割的文件名="+substring);
        if ("jpg".equals(substring) || "png".equals(substring) || "jpeg".equals(substring))
        {
            String finalPictureName = "";
            if (login.getImageAddress() != null) {
                finalPictureName = login.getImageAddress();
            }else {
                finalPictureName = System.currentTimeMillis() + originalFilename;
            }
            log.warn("文件的最终名="+finalPictureName);
            //创建文件
            file.transferTo(new File(realPath,finalPictureName));
            //修改用户数据库图片地址
            userService.<UserDto>modifyUser(new UserDto(null,null,null,finalPictureName,null,0),login.getUsername());
            return resultUtil.result(200,"上传成功");
        }

        return resultUtil.result(500,"照片格式不对，需要jpg、png、jpeg");

    }

    @Override
    @GetMapping("getAllBlog")
    public Map<String, Object> queryAccountAllBlog() {
        List<BlogDto> blogDtoList = blogService.queryAllBLogByUsername(util.getTokenUser().getUsername());
        return resultUtil.result(200,"查询成功",blogDtoList);
    }

    @Override
    @GetMapping("lookOver")
    public Map<String, Object> lookOver() {
        UserDto tokenUser = util.getTokenUser();
        UserDto login = userService.login(tokenUser.getUsername(), tokenUser.getPassword());
        return resultUtil.result(200,"查询成功",login);
    }

    /**
     * 头像下载
     */
    @GetMapping("/down")
    @Operation(summary = "下载头像接口")
    public Map<String, Object> downPicture() throws IOException {
        UserDto tokenUser = util.getTokenUser();
        UserDto login = userService.login(tokenUser.getUsername(), tokenUser.getPassword());
        if (login.getImageAddress()  == null) {
            return    resultUtil.result(500,"暂时没有上传头像");
        }
        //文件地址
        String filePath = realPath + "\\"+login.getImageAddress();
        //文件名
        String fileName = login.getImageAddress();
        log.warn("文件名=" + fileName);
        //设置响应头用来可以下载文件，如果文件名是中文名下载会出现不显示的情况解决方法：
        response.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(fileName,"utf-8"));
        //读取文件
        BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(filePath));
        //写出文件
        ServletOutputStream outputStream = response.getOutputStream();
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes,0,len);
            //刷新缓存
            outputStream.flush();
        }
        //关闭容器
        outputStream.close();
        inputStream.close();
        return resultUtil.result(200,"下载成功");
    }

}
